"""
项目管理API路由
提供项目管理的RESTful API接口
"""

from fastapi import APIRouter, Depends, HTTPException, WebSocket, Query
from sqlalchemy.orm import Session
from typing import List, Optional, Dict, Any
import uuid
from datetime import datetime
from src.services.project_websocket_service import project_websocket_service
from src.research_core.project_state import create_project_state, ProjectManagementState
from src.research_core.project_workflow import get_global_workflow_pool, get_project_workflow, execute_project_workflow
from src.utils.logging import get_logger
from src.config.database import get_db
from src.services.project_service import ProjectService
from src.models.project import Project
from src.services.enhanced_collaboration_service import get_enhanced_collaboration_service

logger = get_logger(__name__)

router = APIRouter(prefix="/projects", tags=["项目管理"])

@router.post("/", response_model=Dict[str, Any])
async def create_project(
    name: str,
    description: Optional[str] = None,
    db: Session = Depends(get_db)
):
    """创建新项目"""
    try:
        project_service = ProjectService(db)
        
        # 创建项目状态
        project_id = str(uuid.uuid4())
        project_state = create_project_state(project_id, name, description or "")
        
        # 保存到数据库
        project = project_service.create_project(name, description, dict(project_state))
        
        if not project:
            raise HTTPException(status_code=500, detail="创建项目失败")
        
        logger.info(f"创建新项目: {name} (ID: {project_id})")
        
        return {
            "success": True,
            "project_id": str(project.id),
            "message": f"项目 '{name}' 创建成功"
        }
    except Exception as e:
        logger.error(f"创建项目失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"创建项目失败: {str(e)}")

@router.get("/", response_model=List[Dict[str, Any]])
async def list_projects(db: Session = Depends(get_db)):
    """获取项目列表"""
    try:
        project_service = ProjectService(db)
        projects = project_service.get_all_projects()
        
        result = []
        for project in projects:
            result.append({
                "id": str(project.id),
                "name": project.name,
                "description": project.description,
                "created_at": project.created_at.isoformat() if project.created_at is not None else None,
                "updated_at": project.updated_at.isoformat() if project.updated_at is not None else None
            })
        
        return result
    except Exception as e:
        logger.error(f"获取项目列表失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取项目列表失败: {str(e)}")

@router.get("/{project_id}", response_model=Dict[str, Any])
async def get_project(project_id: str, db: Session = Depends(get_db)):
    """获取项目详情"""
    try:
        project_service = ProjectService(db)
        project = project_service.get_project(project_id)
        
        if not project:
            raise HTTPException(status_code=404, detail="项目不存在")
        
        return {
            "id": str(project.id),
            "name": project.name,
            "description": project.description,
            "state": project.state,
            "created_at": project.created_at.isoformat() if project.created_at is not None else None,
            "updated_at": project.updated_at.isoformat() if project.updated_at is not None else None
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取项目详情失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取项目详情失败: {str(e)}")

@router.post("/{project_id}/start", response_model=Dict[str, Any])
async def start_project_workflow(project_id: str, db: Session = Depends(get_db)):
    """启动项目工作流"""
    try:
        project_service = ProjectService(db)
        project = project_service.get_project(project_id)
        
        if not project:
            raise HTTPException(status_code=404, detail="项目不存在")
        
        # 获取项目状态（从数据库字段中提取）
        project_state_data = dict(project.state) if isinstance(project.state, dict) else {}
        
        # 确保所有必需字段都存在
        required_fields = [
            "project_id", "project_name", "project_description", "project_phase",
            "requirements_analysis", "product_design", "ui_ux_design", "development_code",
            "test_cases", "test_results", "team_members", "feedback_history",
            "collaboration_data", "version_history", "last_updated", "iteration_count",
            "iteration_history", "decision_history", "quality_metrics", "adaptive_thresholds",
            "question", "search_query", "search_results", "research_complete",
            "final_answer", "images", "tables", "multimodal_content"
        ]
        
        project_name = str(project.name) if project.name is not None else "未知项目"
        project_description = str(project.description) if project.description is not None else ""
        
        for field in required_fields:
            if field not in project_state_data or project_state_data[field] is None:
                # 使用默认值填充缺失字段
                default_state = create_project_state(project_id, project_name, project_description)
                field_value = default_state.get(field)
                if field_value is not None:
                    project_state_data[field] = field_value
        
        # 确保所有字段都存在且类型正确
        from sqlalchemy import Column
        # 处理可能的SQLAlchemy列元素
        def safe_get_value(data, key, default):
            value = data.get(key, default)
            # 如果是SQLAlchemy列元素，返回默认值
            if isinstance(value, Column):
                return default
            return value
            
        project_state = ProjectManagementState(
            project_id=safe_get_value(project_state_data, "project_id", project_id),
            project_name=safe_get_value(project_state_data, "project_name", project_name),
            project_description=safe_get_value(project_state_data, "project_description", project_description),
            project_phase=safe_get_value(project_state_data, "project_phase", "requirements"),
            requirements_analysis=safe_get_value(project_state_data, "requirements_analysis", {}),
            product_design=safe_get_value(project_state_data, "product_design", {}),
            ui_ux_design=safe_get_value(project_state_data, "ui_ux_design", {}),
            development_code=safe_get_value(project_state_data, "development_code", ""),
            test_cases=safe_get_value(project_state_data, "test_cases", []),
            test_results=safe_get_value(project_state_data, "test_results", {}),
            team_members=safe_get_value(project_state_data, "team_members", {}),
            feedback_history=safe_get_value(project_state_data, "feedback_history", []),
            collaboration_data=safe_get_value(project_state_data, "collaboration_data", {}),
            version_history=safe_get_value(project_state_data, "version_history", []),
            last_updated=safe_get_value(project_state_data, "last_updated", datetime.now().isoformat()),
            iteration_count=safe_get_value(project_state_data, "iteration_count", 0),
            iteration_history=safe_get_value(project_state_data, "iteration_history", []),
            decision_history=safe_get_value(project_state_data, "decision_history", []),
            quality_metrics=safe_get_value(project_state_data, "quality_metrics", {}),
            adaptive_thresholds=safe_get_value(project_state_data, "adaptive_thresholds", {}),
            user_feedback=safe_get_value(project_state_data, "user_feedback", ""),
            feedback_processed=safe_get_value(project_state_data, "feedback_processed", False),
            question=safe_get_value(project_state_data, "question", ""),
            search_query=safe_get_value(project_state_data, "search_query", ""),
            search_results=safe_get_value(project_state_data, "search_results", ""),
            research_complete=safe_get_value(project_state_data, "research_complete", False),
            final_answer=safe_get_value(project_state_data, "final_answer", ""),
            images=safe_get_value(project_state_data, "images", []),
            tables=safe_get_value(project_state_data, "tables", []),
            multimodal_content=safe_get_value(project_state_data, "multimodal_content", {})
        )
        
        # 获取工作流
        workflow_pool = get_global_workflow_pool()
        workflow = get_project_workflow(workflow_pool, project_id)
        
        # 执行工作流
        result = execute_project_workflow(workflow, project_state)
        
        if result["success"]:
            # 更新项目状态到数据库
            project_service.update_project_state(project_id, result["final_state"])
            
            logger.info(f"项目工作流启动成功: {project_id}")
            
            return {
                "success": True,
                "message": "项目工作流启动成功",
                "project_id": project_id
            }
        else:
            logger.error(f"项目工作流执行失败: {result['error']}")
            raise HTTPException(status_code=500, detail=f"工作流执行失败: {result['error']}")
            
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"启动项目工作流失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"启动项目工作流失败: {str(e)}")

@router.post("/{project_id}/assign-role", response_model=Dict[str, Any])
async def assign_project_role(
    project_id: str,
    user_id: str,
    role: str,
    db: Session = Depends(get_db)
):
    """分配项目角色"""
    try:
        project_service = ProjectService(db)
        project = project_service.get_project(project_id)
        
        if not project:
            raise HTTPException(status_code=404, detail="项目不存在")
        
        # 更新项目状态中的团队信息
        project_state = dict(project.state) if isinstance(project.state, dict) else {}
        
        # 确保team_members字段存在
        if "team_members" not in project_state:
            project_state["team_members"] = {}
        
        if role not in project_state["team_members"]:
            project_state["team_members"][role] = []
        
        if user_id not in project_state["team_members"][role]:
            project_state["team_members"][role].append(user_id)
        
        # 更新数据库中的项目状态
        if not project_service.update_project_state(project_id, project_state):
            raise HTTPException(status_code=500, detail="更新项目状态失败")
        
        logger.info(f"分配角色成功: 用户 {user_id} -> {role} (项目: {project_id})")
        
        return {
            "success": True,
            "message": f"角色分配成功: {user_id} -> {role}",
            "project_id": project_id
        }
    except Exception as e:
        logger.error(f"分配角色失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"分配角色失败: {str(e)}")

@router.websocket("/{project_id}/collaborate")
async def project_websocket_collaborate(
    websocket: WebSocket,
    project_id: str,
    user_id: str = Query(..., description="用户ID"),
    db: Session = Depends(get_db)
):
    """项目WebSocket协作端点"""
    try:
        project_service = ProjectService(db)
        project = project_service.get_project(project_id)
        
        if not project:
            await websocket.close(code=1008, reason="项目不存在")
            return
        
        # 处理WebSocket连接
        user_info = {
            "user_id": user_id,
            "project_id": project_id,
            "joined_at": datetime.now().isoformat()
        }
        
        await project_websocket_service.handle_project_connection(
            websocket, project_id, user_id, user_info
        )
        
    except Exception as e:
        logger.error(f"项目WebSocket连接错误: {str(e)}")
        try:
            await websocket.close(code=1011, reason=f"服务器错误: {str(e)}")
        except:
            pass

@router.get("/{project_id}/collaboration/users", response_model=Dict[str, Any])
async def get_project_collaboration_users(project_id: str, db: Session = Depends(get_db)):
    """获取项目协作用户列表"""
    try:
        project_service = ProjectService(db)
        project = project_service.get_project(project_id)
        
        if not project:
            raise HTTPException(status_code=404, detail="项目不存在")
        
        users = project_websocket_service.get_project_users(project_id)
        
        return {
            "success": True,
            "project_id": project_id,
            "users": users,
            "count": len(users)
        }
    except Exception as e:
        logger.error(f"获取协作用户列表失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取协作用户列表失败: {str(e)}")

@router.get("/{project_id}/collaboration/history", response_model=Dict[str, Any])
async def get_collaboration_history(
    project_id: str,
    limit: int = Query(50, ge=1, le=1000),
    db: Session = Depends(get_db)
):
    """获取协作操作历史"""
    try:
        project_service = ProjectService(db)
        project = project_service.get_project(project_id)
        
        if not project:
            raise HTTPException(status_code=404, detail="项目不存在")
        
        history = project_websocket_service.get_collaboration_history(project_id, limit)
        
        return {
            "success": True,
            "project_id": project_id,
            "history": history,
            "count": len(history)
        }
    except Exception as e:
        logger.error(f"获取协作历史失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取协作历史失败: {str(e)}")

# 新增文档版本控制和冲突解决相关接口
@router.get("/{project_id}/documents/{document_id}/versions", response_model=Dict[str, Any])
async def get_document_versions(project_id: str, document_id: str):
    """获取文档版本历史"""
    try:
        collaboration_service = get_enhanced_collaboration_service()
        full_document_id = f"{project_id}_{document_id}"
        
        versions = collaboration_service.manager.document_versions.get(full_document_id, {})
        current_revision = collaboration_service.manager.get_document_revision(full_document_id)
        
        return {
            "success": True,
            "document_id": document_id,
            "current_revision": current_revision,
            "versions": list(versions.keys())
        }
    except Exception as e:
        logger.error(f"获取文档版本失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取文档版本失败: {str(e)}")

@router.get("/{project_id}/documents/{document_id}/content", response_model=Dict[str, Any])
async def get_document_content(project_id: str, document_id: str, revision: Optional[int] = None):
    """获取文档内容（可指定版本）"""
    try:
        collaboration_service = get_enhanced_collaboration_service()
        full_document_id = f"{project_id}_{document_id}"
        
        if revision is not None:
            # 获取指定版本的内容
            versions = collaboration_service.manager.document_versions.get(full_document_id, {})
            content = versions.get(revision, "")
        else:
            # 获取最新内容
            content = collaboration_service.manager.get_document_content(full_document_id)
        
        return {
            "success": True,
            "document_id": document_id,
            "content": content,
            "revision": revision or collaboration_service.manager.get_document_revision(full_document_id)
        }
    except Exception as e:
        logger.error(f"获取文档内容失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取文档内容失败: {str(e)}")

@router.post("/{project_id}/documents/{document_id}/resolve-conflict", response_model=Dict[str, Any])
async def resolve_document_conflict(
    project_id: str, 
    document_id: str,
    resolution_data: Dict[str, Any]
):
    """解决文档冲突"""
    try:
        collaboration_service = get_enhanced_collaboration_service()
        full_document_id = f"{project_id}_{document_id}"
        
        # 获取冲突信息
        resolved_content = resolution_data.get("resolved_content", "")
        resolved_revision = resolution_data.get("resolved_revision", 0)
        
        # 更新文档内容
        collaboration_service.manager.documents[full_document_id] = resolved_content
        collaboration_service.manager.document_revisions[full_document_id] = resolved_revision
        
        # 广播冲突解决消息
        await collaboration_service.broadcast_to_document(
            {
                "type": "conflict_resolved",
                "document_id": document_id,
                "content": resolved_content,
                "revision": resolved_revision
            },
            full_document_id
        )
        
        return {
            "success": True,
            "message": "文档冲突已解决",
            "document_id": document_id,
            "revision": resolved_revision
        }
    except Exception as e:
        logger.error(f"解决文档冲突失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"解决文档冲突失败: {str(e)}")

@router.get("/{project_id}/documents/{document_id}/operations", response_model=Dict[str, Any])
async def get_document_operations(
    project_id: str, 
    document_id: str,
    limit: int = Query(100, ge=1, le=1000)
):
    """获取文档操作历史"""
    try:
        collaboration_service = get_enhanced_collaboration_service()
        full_document_id = f"{project_id}_{document_id}"
        
        operations = collaboration_service.manager.get_operation_history(full_document_id, limit)
        
        return {
            "success": True,
            "document_id": document_id,
            "operations": operations,
            "count": len(operations)
        }
    except Exception as e:
        logger.error(f"获取文档操作历史失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取文档操作历史失败: {str(e)}")
